package com.imooc.exception;

import com.imooc.enums.ErrorMsg;
import com.imooc.utils.CommonJsonResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 逸尘风清
 * @date 2021/5/10
 * @time 11:10
 * 描述：
 */

@ControllerAdvice  // 拦截异常注解
public class GlobalExceptionHandler {
    private final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(Exception.class)  // 指定对应异常类处理方案
    @ResponseBody
    public Object handleException(Exception e){
        log.error("Default Exception：",e);
        return CommonJsonResult.errorMsg(ErrorMsg.SYSTEM_ERROR);
    }

    // 处理上面自定义CustomException异常类捕获到的异常
    @ExceptionHandler(CustomException.class)
    @ResponseBody
    public Object handleMallException(CustomException e){
        log.error("CustomException：",e);
        return CommonJsonResult.errorMsg(e.getCode(),e.getMessage());
    }

    // 处理方法参数不合法的异常
    // 适用于@Valid验证参数合法性如下：当name属性为空或者长度不在2到6都会被这个MethodArgumentNotValidException.class捕获到
    // @Size(min = 2, max = 6)  //长度范围
    // @NotNull  // 不为空
    // private String name;

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public CommonJsonResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e){
        log.error("MethodArgumentNotValidException：",e);
        return handleBindingResult(e.getBindingResult());
    }

    // CommonJsonResult，在另外一篇文章中有记录
    private CommonJsonResult handleBindingResult(BindingResult result){
        // 把异常处理为对外暴露的提示
        List<String> list = new ArrayList<>();
        if(result.hasErrors()){
            List<ObjectError> allErrors = result.getAllErrors();
            for(int i = 0; i < allErrors.size(); i++){
                ObjectError objectError = allErrors.get(i);
                String message = objectError.getDefaultMessage();
                list.add(message);
            }
        }
        if(list.size() == 0){  // 通常来说不会为空
            return CommonJsonResult.errorMsg(ErrorMsg.ERROR_PARAMS);
        }

        return CommonJsonResult.errorMsg(ErrorMsg.ERROR_PARAMS.getCode(), list.toString());
    }

    @ExceptionHandler(MaxUploadSizeExceededException.class)
    @ResponseBody
    public CommonJsonResult handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e){
        log.error("MethodArgumentNotValidException：",e);
        return CommonJsonResult.errorMsg(ErrorMsg.UPLOAD_FILE_SIZE_ERROR);
    }
}
